package cn.darkhorse.mesadmin.controller.device;

import cn.darkhorse.alarm.service.AlarmRecordInfoService;
import cn.darkhorse.device.dao.HistoryDataDao;
import cn.darkhorse.device.iot.bo.DeviceVO;
import cn.darkhorse.device.iot.bo.HistoryDataVO;
import cn.darkhorse.device.iot.bo.IndexMonitorVO;
import cn.darkhorse.device.iot.bo.RealDataDetailVO;
import cn.darkhorse.device.iot.cache.IotCacheServiceI;
import cn.darkhorse.device.iot.constant.IotConstant;
import cn.darkhorse.device.pojo.*;
import cn.darkhorse.device.service.IotInstructParamsService;
import cn.darkhorse.device.service.IotPointTableService;
import cn.darkhorse.device.service.MesDeviceService;
import cn.darkhorse.device.service.MesDeviceStatusParseParamService;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.toolkit.SqlRunner;
import com.ruoyi.common.config.MqttClientConfig;
import com.ruoyi.common.config.MqttPusher;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.utils.poi.MyExcelUtil;
import com.ruoyi.system.service.ISysUserService;
import lombok.Data;
import org.apache.commons.lang.StringEscapeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 设备监控详情，历史数据查看
 * @author yuanjun
 * @since 2023/5/8 9:49
 */
@RestController
@RequestMapping("/iot/monitor")
public class DeviceMonitorController {
    private static final Logger log = LoggerFactory.getLogger(DeviceMonitorController.class);

    @Resource
    private IotCacheServiceI iotCacheService;
    @Resource
    private MesDeviceService mesDeviceService;
    @Resource
    private MesDeviceStatusParseParamService mesDeviceStatusParseParamService;
    @Resource
    private RedisCache cache;
    @Resource
    private HistoryDataDao historyDataDao;
    @Resource
    private ISysUserService userService;
    @Resource
    private AlarmRecordInfoService alarmRecordInfoService;
    @Resource
    private IotPointTableService pointTableService;
    @Resource
    private IotInstructParamsService instructParamsService;
    /**
     * 数据采集设备监控首页
     * @return
     */
    @RequestMapping("/index")
    public AjaxResult getAllDevice(String deviceName,String companyName, String status) {
        long millis = System.currentTimeMillis();
        // 查询条件
        LambdaQueryWrapper<MesDevice> queryWrapper = new LambdaQueryWrapper<MesDevice>()
                .orderByDesc(MesDevice::getGmtCreate);

        if (StringUtils.isNotEmpty(deviceName)) {
            queryWrapper.like(MesDevice::getName, deviceName);
        }

        queryWrapper.isNotNull(MesDevice::getGatewayDeviceId);

        List<MesDevice> list = mesDeviceService.list(queryWrapper);
        IndexMonitorVO vo = new IndexMonitorVO();
        if (list == null || list.isEmpty()){
            return AjaxResult.success(vo);
        }

        List<MesDeviceStatusParseParam> mesDeviceStatusParseParams = mesDeviceStatusParseParamService.list(new LambdaQueryWrapper<MesDeviceStatusParseParam>());
        Map<String, MesDeviceStatusParseParam> parseParamMap = mesDeviceStatusParseParams.stream()
                .collect(Collectors.toMap(MesDeviceStatusParseParam::getGatewayDeviceId, param -> param));

        vo.setTotalNum(list.size());
        List<DeviceVO> deviceVOS = new ArrayList<>();

        list.forEach(device-> {

            // 获取实时数据
            DeviceVO deviceVO = new DeviceVO();
            BeanUtils.copyProperties(device, deviceVO);
            List<RealDataDetailVO> realDataList = getRealDataList(device.getGatewayDeviceId(),0);

            if (device.getDeviceOnline() == null) {
                return;
            }
            if (deviceVO.getDeviceOnline()) {
                vo.setOnlineNum(vo.getOnlineNum() + 1);
                deviceVO.addStatus(IotConstant.DEVICE_STATUS_ONLINE);
                // 根据实时数据判断设备状态
                checkDeviceStatus(device.getGatewayDeviceId(),realDataList, vo, deviceVO,parseParamMap.get(device.getGatewayDeviceId()));

                boolean checked = alarmRecordInfoService.checkAlarmStatus(deviceVO.getId());

                if (checked){
                    deviceVO.addStatus(IotConstant.DEVICE_STATUS_ALARM);
                    vo.setAlarmNum(vo.getAlarmNum() + 1);
                }
                //bug 7939
                // deviceVO.setRealDataList(realDataList);
            }
            deviceVO.setRealDataList(realDataList);
            if (!deviceVO.getDeviceOnline()) {
                vo.setOfflineNum(vo.getOfflineNum() + 1);
                deviceVO.addStatus(IotConstant.DEVICE_STATUS_OFFLINE);
            }

            if (IotConstant.DEVICE_STATUS_ALL.equals(status)) {
                deviceVOS.add(deviceVO);
            }

            if (deviceVO.getStatus() != null && deviceVO.getStatus().contains(status)) {
                deviceVOS.add(deviceVO);
            }

        });

        List<DeviceVO> voList = deviceVOS.stream()
                .sorted(Comparator.comparing(DeviceVO::getDeviceOnline).reversed())
                .collect(Collectors.toList());
        vo.setAllDevice(voList);
        System.out.println("end耗时:"+(System.currentTimeMillis()-millis));
        return AjaxResult.success(vo);
    }

    /**
     * 根据实时数据监测当前设备状态
     * @param gatewayDeviceId
     * @param realDataList
     * @param vo
     * @param deviceVO
     */
    private void checkDeviceStatus(String gatewayDeviceId,List<RealDataDetailVO> realDataList, IndexMonitorVO vo, DeviceVO deviceVO,MesDeviceStatusParseParam param) {
        Map<String, String> pointValues = realDataList.stream()
                .collect(Collectors.toMap(RealDataDetailVO::getPointId, RealDataDetailVO::getSourceValue));
        String key = IotConstant.CACHE_MQTT_DEVICE_STATUS + gatewayDeviceId;
        Object cacheObject = cache.getCacheObject(key);
        if (cacheObject == null) {
//            // 从数据库中加载，数据库中找不到直接返回
//            MesDeviceStatusParseParam param = mesDeviceStatusParseParamService.getOne(new LambdaQueryWrapper<MesDeviceStatusParseParam>()
//                    .eq(MesDeviceStatusParseParam::getGatewayDeviceId, gatewayDeviceId));
            if (param != null) {
                cache.setCacheObject(key, param.getParameters());
            }else {
                return;
            }

            cacheObject = cache.getCacheObject(key);
        }

        JSONArray params = JSONArray.parse(cacheObject.toString());
        params.forEach(item-> {
            Object statusType = JSONObject.parse(item.toString()).get(IotConstant.STATUS_TYPE);
            String pointId = JSONObject.parse(item.toString()).get(IotConstant.POINT_ID).toString();
            if (IotConstant.DEVICE_STATUS_PARAM_FIELD_STATUS_TYPE_RUN.equals(statusType.toString())) {
                // 判断设备运行

                String yes = JSONObject.parse(item.toString()).get(IotConstant.DEVICE_STATUS_PARAM_FIELD_YES).toString();
                String no = JSONObject.parse(item.toString()).get(IotConstant.DEVICE_STATUS_PARAM_FIELD_NO).toString();
                String sourceValue = pointValues.get(pointId);

                if (yes.equals(sourceValue)) {
                    vo.setRunNum(vo.getRunNum() + 1);
                    deviceVO.addStatus(IotConstant.DEVICE_STATUS_RUN);
                }

                if (no.equals(sourceValue)) {
                    vo.setStopNum(vo.getStopNum() + 1);
                    deviceVO.addStatus(IotConstant.DEVICE_STATUS_STOP);
                }
            }

            if (IotConstant.DEVICE_STATUS_PARAM_FIELD_STATUS_TYPE_ALARM.equals(statusType.toString())) {
                // 判断设备预警
                String yes = JSONObject.parse(item.toString()).get(IotConstant.DEVICE_STATUS_PARAM_FIELD_YES).toString();
                String no = JSONObject.parse(item.toString()).get(IotConstant.DEVICE_STATUS_PARAM_FIELD_NO).toString();
                String sourceValue = pointValues.get(pointId);

                if (yes.equals(sourceValue)) {
                    vo.setAlarmNum(vo.getAlarmNum() + 1);
                    deviceVO.addStatus(IotConstant.DEVICE_STATUS_ALARM);
                }
            }

            if (IotConstant.DEVICE_STATUS_PARAM_FIELD_STATUS_TYPE_MAINTENANCE.equals(statusType.toString())) {
                // 判断设备检修
                String yes = JSONObject.parse(item.toString()).get(IotConstant.DEVICE_STATUS_PARAM_FIELD_YES).toString();
                String no = JSONObject.parse(item.toString()).get(IotConstant.DEVICE_STATUS_PARAM_FIELD_NO).toString();
                String sourceValue = pointValues.get(pointId);

                if (yes.equals(sourceValue)) {
                    vo.setMaintenanceNum(vo.getMaintenanceNum() + 1);
                    deviceVO.addStatus(IotConstant.DEVICE_STATUS_MAINTENANCE);
                }
            }
        });
    }


    /**
     * 查看详情，包含基础信息 和 实时信息
     * @param id mes_device表的id
     * @return
     */
    @RequestMapping("/view")
    public AjaxResult view(Long id) {
        MesDevice device = mesDeviceService.getById(id);
        if (device == null) {
            return AjaxResult.error(String.format("未找到ID为：%s 的设备信息",id));
        }

        DeviceVO vo = new DeviceVO();
        BeanUtils.copyProperties(device, vo);

        if (StringUtils.isNotEmpty(device.getGatewayDeviceId())) {
            vo.setRealDataList(getRealDataList(device.getGatewayDeviceId(),0));
        }

        return AjaxResult.success(vo);
    }
    /**
     * 获取历史数据
     * @param id
     * @return
     */
    @RequestMapping("/history-data")
    public AjaxResult getHistoryData(Long id ,Integer pageNum, Integer pageSize,String beginTime, String endTime) {
        HistoryDataVO vo = new HistoryDataVO();
        MesDevice device = mesDeviceService.getById(id);
        if (StringUtils.isEmpty(device.getHistoryTableName())) {
            //bug  7926
            // return AjaxResult.error(String.format("ID: %s的设备，未设置历史表", id));
            return AjaxResult.success(vo);
        }

        List<Map<String, Object>> tables = historyDataDao.checkTableExists(device.getHistoryTableName());
        if (tables.size() == 0) {
            return AjaxResult.error("设备属性表不存在，请设置后重试");
        }

        // 获取总条数
        String sql = String.format("select count(0) from %s where created_at between '%s' and '%s'" , device.getHistoryTableName(),beginTime,endTime);
        long count = SqlRunner.db().selectCount(sql);
        // 获取分页数据
        List<Map<String, Object>> list = historyDataDao.getList(device.getHistoryTableName(), pageNum , pageSize,beginTime, endTime);

        vo.setTotal(count);
        vo.setRows(translateText(device.getGatewayDeviceId(), list));

        return AjaxResult.success(vo);
    }

    /**
     * 获取历史数据
     * @param id
     * @return
     */
    @RequestMapping("/export-history")
    public void exportHistory(Long id , Integer pageNum, Integer pageSize, String beginTime, String endTime, HttpServletResponse response) {
        HistoryDataVO vo = new HistoryDataVO();
        MesDevice device = mesDeviceService.getById(id);
        if (StringUtils.isEmpty(device.getHistoryTableName())) {
            //bug  7926
            // return AjaxResult.error(String.format("ID: %s的设备，未设置历史表", id));
            throw new RuntimeException("设备属性表不存在，请设置后重试");
        }

        List<Map<String, Object>> tables = historyDataDao.checkTableExists(device.getHistoryTableName());
        if (tables.size() == 0) {
            throw new RuntimeException("设备属性表不存在，请设置后重试");
        }

        pageNum = 1;
        pageSize = 1000000;
        // 获取分页数据
        long currented = System.currentTimeMillis();
        System.out.println(currented);
        List<Map<String, Object>> list = historyDataDao.getList(device.getHistoryTableName(), pageNum , pageSize,beginTime, endTime);
        System.out.println(System.currentTimeMillis()-currented);
        if (list.isEmpty()){
            return;
        }

        List<JSONObject> objects = translateText(device.getGatewayDeviceId(), list);
        System.out.println(System.currentTimeMillis()-currented);
        MyExcelUtil util = new MyExcelUtil();
        Date date = new Date();
        String format = new SimpleDateFormat("yyyyMMddHHmmss").format(date);

        util.createExcel(response, objects,format+".xlsx",device.getName()+"运行记录"+format);

    }

    /**
     *
     * @param gatewayDeviceId
     * @param fieldName
     * @param beginTime
     * @param endTime
     * @return
     */
    @RequestMapping("/history-data/line-chart-data")
    public AjaxResult getLineChartData(String gatewayDeviceId, String fieldName, String beginTime, String endTime) {
//        TODO: [value]
        String sql = String.format("SELECT  SUBSTRING(CAST( created_at AS CHAR), 1, 19) AS label " +
                        ", %s AS value FROM %s WHERE created_at BETWEEN {0} AND {1}"
                ,fieldName,IotConstant.HISTORY_TABLE_NAME_PRE + gatewayDeviceId);

        List<Map<String, Object>> maps = SqlRunner.db().selectList(sql, beginTime, endTime);
        return AjaxResult.success(maps);
    }

    /**
     * 获取某个设备所有的数值型参数
     * @param gatewayDeviceId
     * @return
     */
    @RequestMapping("/get-numeric-parameters")
    public AjaxResult getNumericParameters(String gatewayDeviceId) {
        // 根据gatewayDeviceId，从缓存中获取各个pointId对应的名称和历史表字段名
        Map<String, Object> pointTable = getPointTable(gatewayDeviceId);
        Map<String, Object> alarmParams = getAlarmParams(gatewayDeviceId);

        // 返回结果 key =
        List<JSONObject> list = new ArrayList<>();
        // 从pointTable和alarmParams中找出类型为数值型的参数
        pointTable.keySet().forEach(pointId-> {
            IotPointTable iotPointTable = (IotPointTable) pointTable.get(pointId);
            Integer dataType = iotPointTable.getDataType();
            //数据类型（0：布尔型1：数值型2：字符型3：枚举型4：二进制
            if (dataType.equals(1)) {
                JSONObject vo = new JSONObject();

                vo.put("value",iotPointTable.getFieldName());
                AlarmParameterSettings alarmParam = (AlarmParameterSettings) alarmParams.get(pointId);
                if (StringUtils.isNotEmpty(alarmParam.getCustomParameterName())) {
                    vo.put("label",alarmParam.getCustomParameterName());
                }else {
                    vo.put("label",alarmParam.getPointName());
                }
                list.add(vo);
            }
        });
        return AjaxResult.success(list);
    }

    /**
     * 从缓存中获取预警参数
     * @param gatewayDeviceId
     * @return
     */
    private Map<String, Object> getAlarmParams(String gatewayDeviceId) {
        String alarmParamsKey = IotConstant.CACHE_MQTT_ALARM_PARAMS + gatewayDeviceId;
        Map<String, Object> alarmParams = cache.getCacheMap(alarmParamsKey);
        if (alarmParams == null || alarmParams.size() == 0) {
            iotCacheService.addAlarmParamToCache(gatewayDeviceId);
        }
        alarmParams = cache.getCacheMap(alarmParamsKey);
        if (alarmParams == null || alarmParams.size() == 0) {
            throw new ServiceException("未找到参数配置信息");
        }

        return alarmParams;
    }

    /**
     * 从缓存中获取点表
     * @param gatewayDeviceId
     * @return
     */
    private Map<String, Object> getPointTable(String gatewayDeviceId) {
        String pointTableKey = IotConstant.CACHE_MQTT_POINT_TABLE + gatewayDeviceId;
        Map<String, Object> pointTableMap = cache.getCacheMap(pointTableKey);
        if (pointTableMap == null || pointTableMap.size() == 0) {
            iotCacheService.addPointTableToCache(gatewayDeviceId);
        }
        pointTableMap = cache.getCacheMap(pointTableKey);
        if (pointTableMap == null || pointTableMap.size() == 0) {
            throw new ServiceException("未找到点表信息");
        }
        return pointTableMap;
    }



    /**
     * 将字段名称，根据点表和alarm_parameter_settings中的配置信息翻译成中文或者加上单位
     * @param list 从数据库中获取的原始数据
     *             List<Map<String, Object>> key = fieldName value=字段的值
     * @return
     */
    private List<JSONObject> translateText(String gatewayDeviceId, List<Map<String, Object>> list) {
        List<JSONObject> result = new ArrayList<>(list.size());
        // 从缓存中获取点表，并且转成成 key为fieldName的map
        String key = IotConstant.CACHE_MQTT_POINT_TABLE  + gatewayDeviceId;
        Map<String, IotPointTable> pointTableMap = cache.getCacheMap(key);
//        pointTableMap = new HashMap<>();
        Map<String, IotPointTable> fieldMap = new HashMap<>();
        Iterator<Map.Entry<String, IotPointTable>> iterator = pointTableMap.entrySet().stream().sorted(Comparator.comparing(o -> o.getValue().getId())).iterator();

        ArrayList<String> fieldNameList = new ArrayList<>();
        while (iterator.hasNext()) {
            Map.Entry<String, IotPointTable> next = iterator.next();
            IotPointTable pointTable = next.getValue();
            fieldMap.put(pointTable.getFieldName(), pointTable);
            fieldNameList.add(pointTable.getFieldName());
        }
        HashMap<String, String> hashMap = new HashMap<>();

        // 将原始数据的参数名称换成配置的中文，将值替换成带单位或者翻译枚举类型
        list.forEach(map -> {
            long millis = System.currentTimeMillis();
//            为保证顺序 不使用keySet
//            Set<String> hashKeys = fieldMap.keySet();
//            同样为了保证展示时的顺序和put的顺序一致, 故使用JSONObject代替Map
            JSONObject object = new JSONObject();
            String dateTime = map.get(IotConstant.FIELD_NAME_CREATED_AT).toString().replace("T"," ");
            if (dateTime.length()>=19){
                dateTime = dateTime.substring(0,19);
            }
            object.put("时间",dateTime);
            fieldNameList.forEach(fieldName-> {
                IotPointTable pointTable = fieldMap.get(fieldName);
                if (null == pointTable) {
                    return;
                }
                Object val = map.get(fieldName);
                if (val!=null){

                    String value = String.valueOf(map.get(fieldName));
                    // 20240920 优化点表翻译 避免多次执行translatePointName方法
                    String pointName = hashMap.get(fieldName);
                    if (pointName==null || pointName.isEmpty()){
                        pointName = translatePointName(gatewayDeviceId, pointTable);
                        hashMap.put(fieldName,pointName);
                    }

                    value = pointTableService.translateValue(pointTable, value);


                    object.put(pointName,value);
                }else {
                    object.put(pointTable.getPointName(),"");
                }

            });

            result.add(object);
            System.out.println(System.currentTimeMillis()-millis);
        });

        return result;
    }

    /**
     * 将历史数据表中的列名，转换为alarmSettingParam中设置的中文
     * @param gatewayDeviceId
     * @param pointTable
     * @return
     */
    private String translatePointName(String gatewayDeviceId, IotPointTable pointTable) {
        AlarmParameterSettings settings = cache.getCacheMapValue(
                IotConstant.CACHE_MQTT_ALARM_PARAMS + gatewayDeviceId, pointTable.getPointId());

        if (StringUtils.isNotEmpty(settings.getCustomParameterName())) {
            return settings.getCustomParameterName();
        }
        return settings.getPointName();
    }

    /**
     * 获取实时数据
     * @param gatewayDeviceId
     * @return
     */
    private List<RealDataDetailVO> getRealDataList(String gatewayDeviceId,int limit) {
        List<RealDataDetailVO> result = new ArrayList<>();
        // 获取从缓存中获取实时数据
        if (StringUtils.isEmpty(gatewayDeviceId)) {
            return result;
        }


        iotCacheService.addAlarmParamToCache(gatewayDeviceId);
        iotCacheService.addPointTableToCache(gatewayDeviceId);

        String paramKey = IotConstant.CACHE_MQTT_ALARM_PARAMS + gatewayDeviceId;
        Map<String, AlarmParameterSettings> alarmParams = cache.getCacheMap(paramKey);
        String pointTableKey = IotConstant.CACHE_MQTT_POINT_TABLE + gatewayDeviceId;
        Map<String, IotPointTable> cacheMap = cache.getCacheMap(pointTableKey);

        Set<String> alarmParamSet = alarmParams.keySet();


        outerLoop:
        for (String pointId : alarmParamSet) {

            AlarmParameterSettings param = alarmParams.get(pointId);
            if (param == null ) {
                break;
            }

            IotPointTable pointTable = cacheMap.get(pointId);
            if (pointTable == null) {
                iotCacheService.addOrUpdatePointTableToCache(gatewayDeviceId);
                cacheMap = cache.getCacheMap(pointTableKey);
                continue outerLoop;
            }

            // 设置label
            RealDataDetailVO detailVO = new RealDataDetailVO();
            detailVO.setId(param.getId());
            if (StringUtils.isEmpty(param.getCustomParameterName())) {
                detailVO.setLabel(param.getPointName());
            }else {
                detailVO.setLabel(param.getCustomParameterName());
            }
            // 设置value
            String realDataKey = IotConstant.CACHE_MQTT_DATA_REAL_DATA + gatewayDeviceId;

            Object realData = cache.getCacheMapValue(realDataKey, pointId);

            String sourceValue = "";
            String value = "";
            if (null != realData) {
                sourceValue = realData.toString();
                value = pointTableService.translateValue(pointTable, sourceValue);;
            }
            detailVO.setValue(value);
            // 设置附加信息
            detailVO.setPointId(pointId);
            detailVO.setDisplay(param.getDisplay());
            detailVO.setSourceValue(sourceValue);
            result.add(detailVO);
        }
        result = result.stream().sorted(Comparator.comparing(RealDataDetailVO::getId)).collect(Collectors.toList());
        if (limit>0){
            result = result.stream().limit(limit).collect(Collectors.toList());
        }
        return result;
    }
//
//    private String translateValue(IotPointTable pointTable, String sourceValue) {
//        String value = sourceValue;
//        Map<String, String> extraInfo = getExtraInfo(pointTable.getExtraJson());
//
//        if (extraInfo == null) {
//            return value;
//        }
//
//        // 根据点表类型翻译value，如果设置了单位，还要加上单位
//        if (IotConstant.POINT_TYPE_BOOLEAN.equals(pointTable.getDataType())) {
//            // 布尔型
//            value = extraInfo.get(sourceValue) == null ? sourceValue : extraInfo.get(sourceValue);
//        }
//
//        if (IotConstant.POINT_TYPE_NUMBER.equals(pointTable.getDataType())) {
//            // 数值型
//            value = extraInfo.get("unit") == null ? sourceValue : sourceValue + " " + extraInfo.get("unit")  ;
//        }
//
//        if (IotConstant.POINT_TYPE_STRING.equals(pointTable.getDataType())) {
//            // 字符型
//            value = sourceValue ;
//        }
//
//        if (IotConstant.POINT_TYPE_ENUM.equals(pointTable.getDataType())) {
//            // 枚举型
//
//            sourceValue = convertByPattern(sourceValue);
//            value =  extraInfo.get(sourceValue) == null ? value : extraInfo.get(sourceValue);
//
//        }
//        return value;
//    }
//    /**
//     * 去掉给定字符串（小数）后面的无效0
//     *
//     * @param value 小数的字符串表示
//     * @return 如果转换失败，返回null
//     */
//    public String convertByPattern(String value) {
//
//        String regex = "^(-?\\d*)(\\.?0*)$";
//        Matcher matcher = Pattern.compile(regex).matcher(value);
//        if (matcher.find()) {
//            return matcher.group(1);
//        }
//        String regex1 = "^(-?\\d*\\.\\d*[1-9])(0*)$";
//        Matcher matcher1 = Pattern.compile(regex1).matcher(value);
//        if (matcher1.find()) {
//            return matcher1.group(1);
//        }
//        return null;
//    }
//
//    /**
//     * 点表中的扩展信息，转换为一个map对象
//     * @param extraJson
//     * @return
//     */
//    private Map<String, String> getExtraInfo(String extraJson) {
//        List<ExtraInfoVO> result = new ArrayList<>();
//        if (StringUtils.isEmpty(extraJson)) {
//            return null;
//        }
//        JSONArray jsonArray = JSONArray.parse(extraJson);
//
//        for (int i = 0; i < jsonArray.size(); i++) {
//            JSONObject o = (JSONObject) jsonArray.get(i);
//            ExtraInfoVO vo = new ExtraInfoVO();
//            vo.setLabel(o.get("label").toString());
//            vo.setValue(o.get("value").toString());
//            result.add(vo);
//        }
//        Map<String, String> collect = result.stream().collect(Collectors.toMap(ExtraInfoVO::getLabel, ExtraInfoVO::getValue));
//        return collect;
//    }
//
//
//    @Data
//    private class ExtraInfoVO {
//        private String label;
//        private String value;
//    }

    @RequestMapping("/camera/list")
    public AjaxResult getCameraList() {
        List<Map<String, Object>> maps = SqlRunner.db().selectList("select id, name as [label] from mes_camera");
        return AjaxResult.success(maps);
    }


    /**
     * 保存设备图片,设备图片存在设备表中
     * @param deviceId
     * @param pictures
     * @return
     */
    @RequestMapping("/pictures/edit")
    public AjaxResult editPictures(Long deviceId, String pictures) {
        /*MesDevice device = new MesDevice();
        device.setId(deviceId);
        device.setPictures(pictures);
        return AjaxResult.success(mesDeviceService.updateById(device));*/
        //bug 7936
        LambdaUpdateWrapper<MesDevice> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(MesDevice::getId,deviceId)
                .set(MesDevice::getPictures,pictures);

        return AjaxResult.success(mesDeviceService.update(updateWrapper));
    }

    @RequestMapping("/pushInstruction")
    public AjaxResult pushInstruction(Long id) {
        return AjaxResult.success(instructParamsService.doPush(id));
    }




    public static void main(String[] args) {
        String unicode = "u5317 u4ead222";
        String[] s = unicode.split(" ");
        StringBuilder stringBuilder = new StringBuilder();

        for (String u : s) {
            stringBuilder.append("\\").append(u);
        }
        unicode = StringEscapeUtils.unescapeJava(stringBuilder.toString());
        System.out.println(unicode);
    }

}
